package schdule

import (
	"golearnpro/pc/engs"
)

type QueueSchdule struct {
	RC       chan engs.Request
	WkerChan chan chan engs.Request // 这个是可以处理 request chan 的 chan
}

func (q *QueueSchdule) Submit(request engs.Request) {
	q.RC <- request
}

func (q *QueueSchdule) WorkerReady(v chan engs.Request) {
	q.WkerChan <- v
}

func (q *QueueSchdule) ConfC(requests chan engs.Request) {
	panic("implement me")
}

func (q *QueueSchdule) WorkerChan() chan engs.Request {
	return make(chan engs.Request)
}

// 总控
func (q *QueueSchdule) Run() {

	q.WkerChan = make(chan chan engs.Request)
	q.RC = make(chan engs.Request)

	go func() {
		// 创建双队列
		// 存放request 的队列
		// 存放worker的队列
		var QueueRequest []engs.Request
		var QueueRequestChan []chan engs.Request

		for {

			var activeRequest engs.Request
			var activeWorker chan engs.Request
			// 什么时候request 可以发给worker?
			// 既有 request 在排队又有worker在排队 就撮合
			if len(QueueRequest) > 0 && len(QueueRequestChan) > 0 {
				activeWorker = QueueRequestChan[0]
				activeRequest = QueueRequest[0]
			}

			select {
			case rc := <-q.RC: // 什么时候有request
				// 收到一个request 就让其排队
				QueueRequest = append(QueueRequest, rc)
			case wk := <-q.WkerChan: // 什么时候有worker事非常独立的事情 独立的事情所以考虑用到了select
				// 收到一个worker也让它排队
				QueueRequestChan = append(QueueRequestChan, wk)

			// 什么时候request 可以发给worker?
			// 既有 request 在排队又有worker在排队 就撮合

			// request 发给worker nil 这行是永远不会被执行的
			case activeWorker <- activeRequest:
				QueueRequestChan = QueueRequestChan[1:]
				QueueRequest = QueueRequest[1:]

			}
		}
	}()
}
